/**
  * @file		MeterRS485.h
  * @author		Krubkib
  * @version	V1.0.0
  * @date		October 19, 2013
  * @brief		UART of Meter
  */

/* Includes ------------------------------------------------------------------*/
#include "helper.h"
#include "MeterRS485.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

volatile uint8_t UART_TxReady = 0;
volatile uint8_t UART_RxByte = 0x00;

/**
  * @brief		Configure USART1 with baud_rate, 8, n, 1
  * @param		baud_rate		Baud rate of UART
  * @retval		None
  */
void UART_config(uint32_t baud_rate)
{
	GPIO_InitTypeDef gpio_init_struct;
	USART_InitTypeDef uart_init_struct;
	NVIC_InitTypeDef nvic_init_struct;
	
	// Enable clock for GPIOB and USART1
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	// Select AF feature of PB6/PB7 for USART1
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

	// Configure GPIOB for USART1 Tx and Rx - PB6 and PB7
	gpio_init_struct.GPIO_Mode = GPIO_Mode_AF;
	gpio_init_struct.GPIO_OType = GPIO_OType_PP;
	gpio_init_struct.GPIO_Speed = GPIO_Speed_50MHz;
	gpio_init_struct.GPIO_Pin = GPIO_Pin_6;
	GPIO_Init(GPIOB, &gpio_init_struct);
	
	gpio_init_struct.GPIO_PuPd = GPIO_PuPd_UP;
	gpio_init_struct.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOB, &gpio_init_struct);	
	
	// Configure USART1 for Tx and Rx with baud rate, 8, n, 1
	uart_init_struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	uart_init_struct.USART_BaudRate = baud_rate;
	uart_init_struct.USART_WordLength = USART_WordLength_8b;
	uart_init_struct.USART_Parity = USART_Parity_No;
	uart_init_struct.USART_StopBits = USART_StopBits_1;
	uart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(USART1, &uart_init_struct);
	
	// Configure NVIC for USART1 IRQ
	nvic_init_struct.NVIC_IRQChannel = USART1_IRQn;
	nvic_init_struct.NVIC_IRQChannelCmd = ENABLE;
	nvic_init_struct.NVIC_IRQChannelPreemptionPriority = 0;
	nvic_init_struct.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&nvic_init_struct);
	
	// Enable USART1 IRQ for RXNE, disable TXE at first
	USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE );
	
	// Enable USART1
	USART_Cmd(USART1, ENABLE);
}


/**
  * @brief		Send one byte through UART
  * @param		val			One byte to send
  * @retval		None
  */
void UART_write(uint8_t val)
{
	USART_SendData(USART1, val);
	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}


/**
  * @brief		Receive one byte through UART
  * @param		None
  * @retval		Received one byte
  */
uint8_t UART_read(void)
{
	uint8_t ch = UART_RxByte;
	UART_RxByte = 0x00;
	return ch;
}


/**
  * @brief		IRQ Handler for USART1
  * @param		None
  * @retval		None
  */
void  USART1_IRQHandler()
{
	if (USART_GetITStatus(USART1,USART_IT_RXNE ) == SET) {
		 UART_RxByte = USART_ReceiveData(USART1);
		
	}
	if (USART_GetITStatus(USART1,USART_IT_TXE ) == SET) {
		USART_ITConfig(USART1,USART_IT_TXE , DISABLE);
	}	
}
